{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python2.x与3.x版本区别"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "\n",
    "print 函数\n",
    "print语句没有了，取而代之的是print()函数。 Python 2.6与Python 2.7部分地支持这种形式的print语法。在Python 2.6与Python 2.7里面，以下三种形式是等价的：\n",
    "\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "fish\n",
      "fish\n"
     ]
    }
   ],
   "source": [
    "# print \"fish\"\n",
    "print (\"fish\") #注意print后面有个空格\n",
    "print(\"fish\") #print()不能带有任何其它参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "\n",
    "Unicode\n",
    "\n",
    "Python 2 有 ASCII str() 类型，unicode() 是单独的，不是 byte 类型。\n",
    "\n",
    "现在， 在 Python 3，我们最终有了 Unicode (utf-8) 字符串，以及一个字节类：byte 和 bytearrays。\n",
    "\n",
    "由于 Python3.X 源码文件默认使用utf-8编码，这就使得以下代码是合法的：\n",
    "\n",
    "\n",
    "'''\n",
    "\n",
    "'''\n",
    "\n",
    "Python 2.x\n",
    "\n",
    "\n",
    ">>> str = \"我爱北京天安门\"\n",
    ">>> str\n",
    "'\\xe6\\x88\\x91\\xe7\\x88\\xb1\\xe5\\x8c\\x97\\xe4\\xba\\xac\\xe5\\xa4\\xa9\\xe5\\xae\\x89\\xe9\\x97\\xa8'\n",
    ">>> str = u\"我爱北京天安门\"\n",
    ">>> str\n",
    "u'\\u6211\\u7231\\u5317\\u4eac\\u5929\\u5b89\\u95e8'\n",
    "\n",
    "\n",
    "\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我爱北京天安门\n"
     ]
    }
   ],
   "source": [
    "# Python 3.x\n",
    "str = \"我爱北京天安门\"\n",
    "print(str)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "\n",
    "\n",
    "\n",
    "除法运算\n",
    "Python中的除法较其它语言显得非常高端，有套很复杂的规则。Python中的除法有两个运算符，/和//\n",
    "\n",
    "首先来说/除法:\n",
    "\n",
    "在python 2.x中/除法就跟我们熟悉的大多数语言，比如Java啊C啊差不多，整数相除的结果是一个整数，把小数部分完全忽略掉，浮点数除法会保留小数点的部分得到一个浮点数的结果。\n",
    "\n",
    "在python 3.x中/除法不再这么做了，对于整数之间的相除，结果也会是浮点数。\n",
    "\n",
    "Python 2.x:\n",
    "\n",
    ">>> 1 / 2\n",
    "0\n",
    ">>> 1.0 / 2.0\n",
    "0.5\n",
    "\n",
    "\n",
    "\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.5\n"
     ]
    }
   ],
   "source": [
    "# python 3.x\n",
    "print(1/2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-1\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "\n",
    "而对于//除法，这种除法叫做floor除法，会对除法的结果自动进行一个floor操作，在python 2.x和python 3.x中是一致的。\n",
    "\n",
    "\n",
    "'''\n",
    "\n",
    "print(-1//2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'''\n",
    "注意的是并不是舍弃小数部分，而是执行 floor 操作，如果要截取整数部分，那么需要使用 math 模块的 trunc 函数\n",
    "\n",
    "'''\n",
    "\n",
    "import math\n",
    "math.trunc(1//2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "\n",
    "\n",
    "异常\n",
    "在 Python 3 中处理异常也轻微的改变了，在 Python 3 中我们现在使用 as 作为关键词。\n",
    "\n",
    "捕获异常的语法由 except exc, var 改为 except exc as var。\n",
    "\n",
    "使用语法except (exc1, exc2) as var可以同时捕获多种类别的异常。 Python 2.6已经支持这两种语法。\n",
    "\n",
    "1. 在2.x时代，所有类型的对象都是可以被直接抛出的，在3.x时代，只有继承自BaseException的对象才可以被抛出。\n",
    "2. 2.x raise语句使用逗号将抛出对象类型和参数分开，3.x取消了这种奇葩的写法，直接调用构造函数抛出对象即可。\n",
    "在2.x时代，异常在代码中除了表示程序错误，还经常做一些普通控制结构应该做的事情，在3.x中可以看出，设计者让异常变的更加专一，只有在错误发生的情况才能去用异常捕获语句来处理。\n",
    "\n",
    "\n",
    "\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "\n",
    "xrange\n",
    "在 Python 2 中 xrange() 创建迭代对象的用法是非常流行的。比如： for 循环或者是列表/集合/字典推导式。\n",
    "\n",
    "这个表现十分像生成器（比如。\"惰性求值\"）。但是这个 xrange-iterable 是无穷的，意味着你可以无限遍历。\n",
    "\n",
    "由于它的惰性求值，如果你不得仅仅不遍历它一次，xrange() 函数 比 range() 更快（比如 for 循环）。尽管如此，对比迭代一次，不建议你重复迭代多次，因为生成器每次都从头开始。\n",
    "\n",
    "在 Python 3 中，range() 是像 xrange() 那样实现以至于一个专门的 xrange() 函数都不再存在（在 Python 3 中 xrange() 会抛出命名异常）。\n",
    "\n",
    "\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-11-d8783cc8e1a6>, line 6)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-11-d8783cc8e1a6>\"\u001b[1;36m, line \u001b[1;32m6\u001b[0m\n\u001b[1;33m    return for i in range(n):\u001b[0m\n\u001b[1;37m             ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "import timeit\n",
    "\n",
    "n = 10000\n",
    "\n",
    "def test_range(n):\n",
    "    return for i in range(n):\n",
    "        pass\n",
    "    \n",
    "print('\\ntiming range()')\n",
    "%timeit test_range(n)\n",
    "\n",
    "timeit range()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "512\n",
      "0b1000000000\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "\n",
    "\n",
    "八进制字面量表示\n",
    "\n",
    "\n",
    "八进制数必须写成0o777，原来的形式0777不能用了；二进制必须写成0b111。\n",
    "\n",
    "新增了一个bin()函数用于将一个整数转换成二进制字串。 Python 2.6已经支持这两种语法。\n",
    "\n",
    "在Python 3.x中，表示八进制字面量的方式只有一种，就是0o1000。\n",
    "\n",
    "python 2.x\n",
    "\n",
    ">>> 0o1000\n",
    "512\n",
    ">>> 01000\n",
    "512\n",
    "python 3.x\n",
    "\n",
    ">>> 01000\n",
    "  File \"<stdin>\", line 1\n",
    "    01000\n",
    "        ^\n",
    "SyntaxError: invalid token\n",
    ">>> 0o1000\n",
    "512\n",
    "不等运算符\n",
    "\n",
    "\n",
    "'''\n",
    "k = 0O1000;# 注意： 0O是大写字母O和小写字母o\n",
    "print(k)\n",
    "\n",
    "print(bin(512))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "\n",
    "不等运算符\n",
    "\n",
    "Python 2.x中不等于有两种写法 != 和 <>\n",
    "\n",
    "Python 3.x中去掉了<>, 只有!=一种写法，还好，我从来没有使用<>的习惯\n",
    "\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "\n",
    "去掉了repr表达式``\n",
    "\n",
    "Python 2.x 中反引号``相当于repr函数的作用\n",
    "\n",
    "Python 3.x 中去掉了``这种写法，只允许使用repr函数，这样做的目的是为了使代码看上去更清晰么？不过我感觉用repr的机会很少，一般只在debug的时候才用，多数时候还是用str函数来用字符串描述对象。\n",
    "\n",
    "def sendMail(from_: str, to: str, title: str, body: str) -> bool:\n",
    "    pass\n",
    "\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "\n",
    "多个模块被改名（根据PEP8）\n",
    "\n",
    "\n",
    "旧的名字\t        新的名字\n",
    "_winreg\twinreg\n",
    "ConfigParser\t    configparser\n",
    "copy_reg\t        copyreg\n",
    "Queue\t            queue\n",
    "SocketServer\t    socketserver\n",
    "repr\t            reprlib\n",
    "\n",
    "StringIO模块现在被合并到新的io模组内。 new, md5, gopherlib等模块被删除。 Python 2.6已经支援新的io模组。\n",
    "\n",
    "httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib被合并到http包内。\n",
    "\n",
    "取消了exec语句，只剩下exec()函数。 Python 2.6已经支援exec()函数。\n",
    "\n",
    "\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "\n",
    "\n",
    "5.数据类型\n",
    "\n",
    "\n",
    "1）Py3.X去除了long类型，现在只有一种整型——int，但它的行为就像2.X版本的long\n",
    "\n",
    "2）新增了bytes类型，对应于2.X版本的八位串，定义一个bytes字面量的方法如下：\n",
    "\n",
    "\n",
    "'''"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
